Reporte Reproducible Univariado

R para Ciencia de Datos en Salud:
Análisis Descriptivo e Inferencia Estadística

Percy Soto-Becerra M.D., M.Sc(c)

InkaStats Data Science Solutions | Medical Branch
@github/psotob91

Crisis de Reproducibilidad

La crisis de Reproducibilidad



  • Calidad de la investigación médica a menudo es baja.

  • Código de baja calidad en investigación médica es parte del problema.

  • Código de baja calidad es más propenso a tener errores.

  • Reproducibilidad a menudo es engorrosa y consume tiempo.

Reporte Reproducible

¿Cómo hacer que un análisis de datos sea reproducible?


  • No cree la tabla “manualmente”.

  • Genere las tablas con código:

    • Es reproducible.
    • Menos propenso a error de digitación o lapsus calamis.
    • Han habido retracciones de ensayos clínicos por errores de tipeo!!
    • Es más rápido, ahorrarás tiempo!!
  • A la tabla descriptiva menudo se la conoce como tablas tipo 1.

    • Puede haber más de una, no hay reglas, solo buenos o malos criterios para presentar resultados.
  • Hay muchos paquetes: {flextable}, {gt},{huxtable}, {kableExtra}, {kable}, etc.

  • Sugerimos {gtsummary} para comenzar:

https://www.danieldsjoberg.com/gtsummary/

Tabla decriptiva reproducible con {gtsummary}

  • Permite crear tablas en formato de revistas biomédicas.

  • Función tbl_summary() para tablas descriptivas univariadas y comparativas (bivariadas)

https://www.danieldsjoberg.com/gtsummary/

Los datos que usaremos

  • Usaremos los datos simulados de un ensayo clínico para evaluar la seguridad de un suplemento en outcomes clinico y fisiologicos de mujeres con menopausia:
id time treat treated age race married2 procedence weight height e2
1 Baseline Placebo 0 33 Mestiza Without couple Callao 59.0 1.4 87.30
1 3 months Placebo 0 32 Mestiza Without couple Callao 59.9 1.3 210.05
2 Baseline Dosis 2 1 27 Mestiza Without couple Santa Anita 62.0 1.5 169.01
2 3 months Dosis 2 1 27 Mestiza Without couple Santa Anita 62.1 1.6 99.91
3 Baseline Dosis 1 1 25 Mestiza Without couple Callao 62.0 1.6 78.76
3 3 months Dosis 1 1 25 Mestiza Without couple Callao 60.0 1.6 155.04
  • Las etiquetas de cada variable son:
Variable Label
id ID participant
time Time's measurement
treat Treatment's group
treated Treated
age Age, years
race Race
married2 Marital status, recat
procedence Distrit of procedence
weight Weight, kg
height Height, m
e2 Estradiol

tbl_summary() paso a paso

tbl_summary() básico

  • Seleccionar las variables que desea reportar con función select(), luego usar tbl_summary():
library(gtsummary)
datos %>% 
  select(age, race, married2, e2) %>% 
  tbl_summary()

  • Cuarto tipo de resumenes: continuous, continuos2, categorical y dichotomous

  • Por defecto, los estadísticos son reportadas como mediana (percentil 25, percentil 75) para variables numéricas y n (%) para variables categóricas/dicotómicas.

  • Las variables codificadas como 0 / 1, TRUE / FALSE o Yes / No son tratadas como dicotómicas.

  • Los valores NA se listan como “Unknown

  • Los atributos de etiqueta se imprimen por defecto.

  • Uno puede realizar más personalizaciones a la tabla.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary()

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous")
  )
  • type: Especifica el tipo de variable para el resumen

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(
      age ~ "{mean} ({sd})", 
      married2 ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(
      c(age, height) ~ "{mean} ({sd})", 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", 
                         "{median} ({p25} - {p75})"), 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", 
                         "{median} ({p25} - {p75})", 
                         "{min} - {max}"), 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

      • Podemos ponerle cuantos estadísticos queramos.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  ) 
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

      • Podemos ponerle cuantos estadísticos queramos.

      • Podemos tener diferentes combinaciones de estadísticos.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label: Cambia o personaliza la etiqueta de la variable.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label: Cambia o personaliza la etiqueta de la variable.

  • digit: Especifica el número de decimales de redondeo.

Reporte de datos perdidos con tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing_text = "Missing data"
  ) 
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

Reporte de datos perdidos con tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing = "always", missing_text = "Missing data"
  )  
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

  • missing: Por defecto se presentan los datos perdidos solo si la variable los tiene “ifany”.

    • missing = “always” siempre presenta datos perdidos.

Reporte de datos perdidos con tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing = "no"
  ) 
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

  • missing: Por defecto se presentan los datos perdidos solo si la variable los tiene “ifany”.

    • missing = “always” siempre presenta datos perdidos, así la variable no los tenga.
    • missing = “no” nunca presenta datos perdidos, así la variable los tenga.

En resumen: {gtsummary} + fórmulas

Personzalización con bold_() / italicize_()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) 

Personzalización con bold_() / italicize_()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels()
  • bold_labels(): negrita a las etiquetas de las variables

Personzalización con bold_*() / italicize_*()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() %>% 
  italicize_levels() 
  • bold_labels(): negrita a las etiquetas de las variables

  • italicize_levels(): cursiva a los niveles (valores) de las variables

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.
library(flextable)
  • Paso 1: Cargar paquete {flextable}

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.
library(flextable)

tabla1 %>% 
  as_flex_table() 

  • Paso 1: Cargar paquete {flextable}

  • Paso 2: Se convierte a objeto de tipo flextable con la función as_flex_table().

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word:
library(flextable)

tabla1 %>% 
  as_flex_table() %>% 
  save_as_docx(path = "Tabla1.docx")
  • Paso 1: Cargar paquete {flextable}

  • Paso 2: Se convierte a objeto de tipo flextable con la función as_flex_table().

  • Paso 3: Se guarda como word con la función save_as_docx()

Guardar tabla como documento MS Word (cont.)

  • El MS Word aparecerá en la carpeta del proyecto:

Guardar tabla como documento MS Word (cont.)

  • Y la tabla en Word lucirá así:

Guardar tabla como documento MS Excel

  • Usamos el paquete {huxtable}
library(huxtable)
  • Con la función as_hux_xlsx convertimos el objeto tbl_summary a un excel con un nombre de archivo que uno defina:
tabla1 %>% 
  as_hux_xlsx(file = "Tabla1.xlsx")
  • La tabla en excel se muestra a continuación:

Nuestro turno


  • Abra el proyecto report_reprod_univ.Rproj y dentro de este, abra el archivo quarto report_reprod_univ.qmd.

  • Siga las instrucciones indicadas en este.

  • Renderice el archivo quarto final.




10:00